# -*- coding: utf-8 -*-
"""
Created on Sat Oct  3 22:19:27 2020

@author: jyh
"""
import logging

import tensorflow as tf
import numpy as np
from tensorflow.keras.models import load_model
from sklearn.preprocessing import OneHotEncoder
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
import xlwt
import re
import os

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

def data_reconstruct_and_prob_compute(data, cnn_model_path, prob_file_out, Len=8):
    # 模型输入的数据长度（字节）
    L_data = Len**2
    L_mesg = len(data[0])  # 填充后每一条报文长度
    d = data[0 : len(data) // L_data * L_data]  # 取模型输入长度的整数倍数据
    posi_label = [list(range(1, L_mesg + 1)) for _ in range(len(data) // L_data)]  # 存放报文每一个字节对应的标号1~……
    posi_label = np.asfarray(posi_label)
    d = np.reshape(d, [-1, L_data])
    posi_label = np.reshape(posi_label, [-1, L_mesg])

    d_target = np.reshape(d, [-1, Len, Len, 1])

    # 制作标签（这里仍假设是二分类问题，如有误请按实际情况修改）
    label_random = np.random.randint(0, 2, size=len(d_target))
    label = OneHotEncoder(sparse=False).fit_transform(label_random[:, np.newaxis])

    # 加载预训练模型
    model = tf.keras.models.load_model(cnn_model_path)

    # 获取预测结果
    y_pred = model.predict(d_target)
    res_ypred = np.argmax(y_pred, axis=1)

    temp3 = np.reshape(res_ypred.T, [len(res_ypred) // L_mesg, -1])
    freq = np.sum(temp3, axis=0)
    p = freq / (len(data) // L_data)
    p = np.reshape(p, [L_mesg, 1])

    # result = np.hstack((posi_label[0:L_mesg], p))
    #
    # # 将结果写入Excel文件
    # try:
    #     import pandas as pd
    #     df_result = pd.DataFrame(result)
    #     df_result.to_excel(prob_file_out + 'result_based_CNN_by_bytes_' + str(Len) + '-' + str(Len) + '_pad.xlsx', index=False)
    # except ImportError:
    #     print("未找到pandas库，无法写入Excel文件，请安装pandas后重试！")
    #     logging.warning("未找到pandas库，无法写入Excel文件，请安装pandas后重试！")
    #
    # print("计算结束，加密概率已保存到Excel文件。")
    # logging.info("计算结束，加密概率已保存到Excel文件。")
    return p

def discrete_funtion_derivative3(x):
    #此方法用了二阶向后微分法求导
    der = []
    x = x + [0,0]
    for k in range(len(x)-2):
        der_temp = (-x[k+2]+4*x[k+1]-3*x[k])/2
        der.append(der_temp)
        pass
    return der

def plot_p(y):
    x = list(range(1,len(y)+1))
    my_font = fm.FontProperties(fname=r'FZXBSJW.ttf')
    my_size = 12
    my_font.set_size(my_size)
    plt.style.use('classic')
    fig,ax = plt.subplots(figsize=(6,4))
    c1 = 'royalblue'
    c2 = 'orangered'
    ax.plot(x,y,ls='-',lw=0.8,c=c1,marker='^',mec=c1,mfc='w',markersize=6,label=u'半监督Acc',markeredgewidth=1)
    ax.set_xlabel(u'字节偏移量(%)',fontproperties=my_font) 
    #ax.set_ylabel(u'准确率',fontsize=my_size)
    # ax.set_ylim(0.79,0.99)
    # ax.set_xlim(0.0,7.2)
    '''设置刻度'''
    # ax.yaxis.set_major_locator(plt.MultipleLocator(0.02))  #设置主要刻度
    plt.xticks(fontproperties=my_font)#设置坐标刻度字体大小
    plt.yticks(fontproperties=my_font)#设置坐标刻度字体大小
    # ax.legend(bbox_to_anchor=(0.995,0.35),fontsize=14,frameon=True, framealpha=1, numpoints=1, markerscale=0.8,labelspacing=0.08,handlelength=1.2)
    ax.grid(axis="y")#画网格
    ax.grid(axis="x")#画网格
    plt.rcParams['axes.unicode_minus']=False
    plt.savefig(r't1.png', dpi=300,bbox_inches = 'tight')

if __name__=="__main__":
    import rpdc_test_data_process
    data_pad,file_out,sel_data,label=rpdc_test_data_process.data_under_test(9000,9000)
    p = data_reconstruct_and_prob_compute(data_pad,r"cnn_model", file_out,Len=8)
    p_derivative = discrete_funtion_derivative3(p)
    plot_p(p)
    plot_p(p_derivative)